﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Text.RegularExpressions;
using Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Models;

namespace Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.ViewModels
{
    public class CodeAnalysisViewModel : ViewModelBase
    {
        private Models.CodeAnalysis analysis;

        private string target;

        private CodeAnalysisStatus status;

        private string message;


        public string FxCopCmdPath
        {
            get { return analysis.FxCopCmdPath; }
            set { analysis.FxCopCmdPath = value; OnPropertyChanged("FxCopCmdPath"); }
        }

        public string FxCopCmdOption
        {
            get { return analysis.FxCopCmdOption; }
            set
            {
                analysis.FxCopCmdOption = value;
                OnPropertyChanged("FxCopCmdOption");
            }
        }

        public string Target
        {
            get { return target; }
            set { target = value; OnPropertyChanged("Target"); }
        }

        public CodeAnalysisStatus Status
        {
            get { return status; }
            set { status = value; OnPropertyChanged("Status"); }
        }

        public string Message
        {
            get { return message; }
            set { message = value; OnPropertyChanged("Message"); }
        }

        public ICollection<ProblemViewModel> Problems { get; private set; }

        public ICollection<RuleViewModel> Rules { get; private set; }


        public CodeAnalysisViewModel()
        {
            analysis = new Models.CodeAnalysis();
            Problems = new List<ProblemViewModel>();
            Rules = new List<RuleViewModel>();
        }


        public void PerformCodeAnalysis()
        {
            NotifyCodeAnalysisStarted();

            try
            {
                analysis.Perform();
                foreach (var problem in analysis.Report.Problems)
                {
                    Problems.Add(new ProblemViewModel(problem));
                }
                foreach (var rule in analysis.Report.Rules)
                {
                    Rules.Add(new RuleViewModel(rule));
                }
                NotifyCodeAnalysisCompleted(analysis.Report.Problems.Count);
            }
            catch (Exception ex)
            {
                NotifyCodeAnalysisFailed(ex);
            }
        }

        private void UpdateTarget()
        {
            var match = Regex.Match(FxCopCmdOption, @"/f:""(.+?)""");
            if (match.Success)
            {
                Target = Path.GetFileNameWithoutExtension(match.Groups[1].Value);
            }
            else
            {
                Target = "FxCop Project File";
            }
        }

        private void NotifyCodeAnalysisStarted()
        {
            Message = "Analyzing...";
            Status = CodeAnalysisStatus.Analyzing;
        }

        private void NotifyCodeAnalysisCompleted(int problemsCount)
        {
            Message = (problemsCount > 0) ? problemsCount + " problems found." : "No problems found.";
            Status = CodeAnalysisStatus.Completed;
        }

        private void NotifyCodeAnalysisFailed(Exception ex)
        {
            Message = ex.Message;
            Status = CodeAnalysisStatus.Failed;
        }
    }
}
